package scene
{
	import actor.Demon;
	import actor.Tower;
	import actor.attribute.DemonAttribute;
	import actor.attribute.TowerAttribute;
	
	import capricornus.actor.Actor;
	import capricornus.actor.Avatar;
	import capricornus.actor.events.ActorEvent;
	import capricornus.core.StageManager;
	import capricornus.io.KeyboardManager;
	import capricornus.scene.events.ActionSceneEvent;
	import capricornus.scene.sceneio.ActionSceneInteractiveController;
	import capricornus.utils.roughtime.RoughTimer;
	import capricornus.utils.roughtime.RoughTimerEvent;
	
	import components.bullets.Bullet;
	
	import flash.display.Sprite;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.text.GridFitType;
	import flash.ui.Keyboard;
	import flash.utils.Dictionary;
	
	import scene.event.SceneEvent;
	import scene.grid.GridType;
	import scene.grid.SceneGridController;
	import scene.grid.SceneTowerHandleController;
	import scene.mission.MissionController;
	import scene.road.RoadController;
	
	public class Scene extends Sprite
	{
		public static var instance:Scene;
		
		//底层，只有这一层有鼠标事件，其他都没
		private var _backLayer:Sprite;
		//放置怪物和塔的层
		private var _actorLayer:Sprite;
		//测试放置塔的层
		private var _testPutLayer:Sprite;
		//子弹层
		private var _bulletLayer:Sprite;
		//提示层
		private var _tipLayer:Sprite;
		
		/**
		 * 存储Actor，不存储怪物
		 */		
		private var _dictActor:Dictionary;
		
		/**
		 * 怪物数量 
		 */		
		private var _demonCount:int = 0;
		/**
		 * 存储怪物 
		 */		
		private var _dictMonster:Dictionary;
		
		/**
		 * 路径管理器 
		 */		
		private var _roadController:RoadController;
		/**
		 * 格子信息管理器 
		 */		
		private var _gridController:SceneGridController;
		/**
		 *  放置塔的管理器
		 */		
		private var _towerHandleController:SceneTowerHandleController;
		/**
		 * 鼠标信息管理器 
		 */		
		private var _interactiveController:ActionSceneInteractiveController;
		
		/**
		 * 关卡管理器 
		 */		
		private var _missionController:MissionController;
		
		private var _timer:RoughTimer;
		
		public function Scene()
		{
			super();
			init();
		}
		
		private function init():void
		{
			instance = this;
			this.mouseEnabled = false;
			
			_dictActor = new Dictionary();
			_dictMonster = new Dictionary();
			
			_backLayer = new Sprite();
			_backLayer.mouseChildren = false;
			addChild( _backLayer );
			
			var m:MapPanel = new MapPanel();
			_backLayer.cacheAsBitmap = true;
			_backLayer.addChild( m );
			
			_actorLayer = new Sprite();
			_actorLayer.cacheAsBitmap = true;              //这句很重要
			_actorLayer.mouseChildren = false;
			_actorLayer.mouseEnabled = false;
			addChild( _actorLayer );
			
			_testPutLayer = new Sprite();
			_testPutLayer.mouseChildren = false;
			_testPutLayer.mouseEnabled = false;
			addChild( _testPutLayer );
			
			_bulletLayer = new Sprite();
			_bulletLayer.mouseChildren = false;
			_bulletLayer.mouseEnabled = false;
			addChild( _bulletLayer );
			
			_tipLayer = new Sprite();
			_tipLayer.mouseChildren = false;
			_tipLayer.mouseEnabled = false;
			addChild( _tipLayer );
			
			_roadController = new RoadController( m );
			_gridController =  new SceneGridController( this );
			_interactiveController = new ActionSceneInteractiveController( this );
			_towerHandleController  = new SceneTowerHandleController( this );
			
			_backLayer.addEventListener( MouseEvent.MOUSE_DOWN, onMouseDown, false, 0, true );
			_timer = new RoughTimer( 50 );
			_timer.addEventListener( RoughTimerEvent.TIMER, onTimerToCreateDemon, false, 0, true );
			_timer.start();
			
			this.addEventListener( MouseEvent.MOUSE_OUT, onSceneMouseOut, false, 0, true );
			this.addEventListener( MouseEvent.MOUSE_OVER, onSceneMouseOver, false, 0, true );
			
			StageManager.stage.addEventListener( KeyboardEvent.KEY_DOWN, onKeydown, false, 0, true );
		}
		
		public function get gridController():SceneGridController
		{
			return _gridController;
		}
		
		public function get demonCount():int
		{
			return _demonCount;
		}
		
		public function get demons():Dictionary
		{
			return _dictMonster;
		}
		
		public function get backLayer():Sprite
		{
			return _backLayer;
		}
		
		public function get actorLayer():Sprite
		{
			return _actorLayer;
		}
		
		public function get testPutLayer():Sprite
		{
			return _testPutLayer;
		}
		
		public function get tipLayer():Sprite
		{
			return _tipLayer;
		}
		
		/**
		 * 添加塔 
		 * @param tower
		 * 
		 */		
		public function addTower( tower:Tower ):void
		{
			addActor( tower );
			tower.setScene( this );
			
			_gridController.setTowerRange( tower.gridI, tower.gridJ, (tower.attribute as TowerAttribute).range, tower );
			_gridController.setTowerRectBlockType( tower.gridI, tower.gridJ, (tower.attribute as TowerAttribute).useGrid, GridType.TOWER );
			
			tower.addEventListener( ActorEvent.ACTOR_DESTROYED, onTowerDestroy, false, 0, true );
		}
		
		/**
		 * 添加怪物 
		 * @param demon
		 * 
		 */		
		public function addDemon( demon:Demon ):void
		{
			addActor( demon );
			
			_dictMonster[demon.attribute.id] = demon;
			_demonCount++;
			
			var ri:int = (demon.attribute as DemonAttribute).roadIndex;
			var arrPath:Array = _roadController.getRoadPathByIndex( ri );
			demon.addMovePath( arrPath );
			
			demon.addEventListener( ActorEvent.ACTOR_DESTROYED, onDemonDestroy, false, 0, true );
			demon.addEventListener( ActorEvent.MOVED, onDemonMoved, false, 0, true );
			
			dispatchEvent( new SceneEvent( SceneEvent.DEMON_COUNT_CHANGED, _demonCount ) );
		}
		
		/**
		 * 添加子弹 
		 * @param bullet
		 * 
		 */		
		public function addBullet( bullet:Bullet ):void
		{
			_bulletLayer.addChild( bullet );
		}
		
		/**
		 * 添加actor，添加怪物不要调用这函数 
		 * @param ac
		 * 
		 */		
		public function addActor( ac:Actor ):void
		{
			_dictActor[ac.attribute.id] = ac;
			_actorLayer.addChild( ac );
			ac.onAddToScene();
		}
		
		/**
		 * 移出actor，非怪物 
		 * @param ac
		 * 
		 */		
		public function removeActor( ac:Actor ):void
		{
			if( _dictActor[ac.attribute.id] != null )
			{
				delete _dictActor[ac.attribute.id];
			}
			if( ac.parent != null )
			{
				_actorLayer.removeChild( ac );
			}
			ac.onRemoveFromScene();
		}
		
		private function onTowerDestroy( e:ActorEvent ):void
		{
			var tower:Tower = e.currentTarget as Tower;
			removeActor( tower );
			
			_gridController.setTowerRange( tower.gridI, tower.gridJ, (tower.attribute as TowerAttribute).range, tower, true );
			_gridController.setTowerRectBlockType( tower.gridI, tower.gridJ, (tower.attribute as TowerAttribute).useGrid, GridType.NONE );
			
			tower.removeEventListener( ActorEvent.ACTOR_DESTROYED, onTowerDestroy );
		}
		
		private function onDemonMoved( e:ActorEvent ):void
		{
			var demon:Demon = e.currentTarget as Demon;
			var arrLast:Array = e.data as Array;
			
			_gridController.setDemonMove( demon, arrLast, [demon.x, demon.y] );
		}
		
		private function onDemonDestroy( e:ActorEvent ):void
		{
			_demonCount--;
			
			var demon:Demon = e.currentTarget as Demon;
			removeActor( demon );
			
			demon.removeEventListener( ActorEvent.ACTOR_DESTROYED, onDemonDestroy );
			demon.removeEventListener( ActorEvent.MOVED, onDemonMoved );
			
			_gridController.setDemonBlockTypeByXY( demon.x, demon.y, demon, true );
			
			delete _dictMonster[demon.attribute.id];
			
			if( _demonCount < 1 )
			{
				dispatchEvent( new SceneEvent( SceneEvent.DEMON_CLEAR, 0 ) );
			}
			dispatchEvent( new SceneEvent( SceneEvent.DEMON_COUNT_CHANGED, _demonCount ) );
		}
		
		private var _towerCount:int = 0;
		private function onMouseDown( e:MouseEvent ):void
		{
			if( KeyboardManager.instance.getKeyState( Keyboard.SPACE ) )
			{
				/*var tower:Tower = Tower.createTowerByID( 1 );
				tower.setLocation( e.localX, e.localY );
				addActor( tower );
				tower.stand();
				_towerCount++;
				trace( _towerCount );*/
			}
		}
		
		private function onKeydown( e:KeyboardEvent ):void
		{
			if( e.keyCode==Keyboard.SPACE )
			{
				_towerHandleController.startPutDownTowerByID( 1 );
			}
		}
		
		private function onTimerToCreateDemon( e:RoughTimerEvent ):void
		{
			if( _demonCount < 400 )
			{
				var demon:Demon = Demon.createByID( Math.random()*7+1 );
				addDemon( demon );
			}
		}
		
		private function onSceneMouseOver( e:MouseEvent ):void
		{
			dispatchEvent( new ActionSceneEvent( ActionSceneEvent.ACTION_SCENE_MOUSE_OVER ) );
		}
		
		private function onSceneMouseOut( e:MouseEvent ):void
		{
			dispatchEvent( new ActionSceneEvent( ActionSceneEvent.ACTION_SCENE_MOUSE_OUT ) );
		}
	}
}


















